package org.dce.screencapturer.components;

import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.DefaultStyledDocument;

@SuppressWarnings("serial")
public class EditorArea 
	extends JScrollPane{

	private JTextArea textArea = new JTextArea();
	private List<EditorAreaListener> listeners = new ArrayList<EditorAreaListener>();
	
	public EditorArea(){
		setOpaque(false);
		setViewportView(textArea);
		ActionMap actionMap = textArea.getActionMap();

		textArea.setDocument(new DefaultStyledDocument());
		
		InputMap inputMap = textArea.getInputMap();

		KeyStroke ksEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
		KeyStroke ksCtrlEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.CTRL_DOWN_MASK);
		KeyStroke ksEscape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
		
		actionMap.put("finish-edit", new AbstractAction(){
			public void actionPerformed(ActionEvent e) {
				commitEdit();
			}
		});

		String defaultEnterAction = (String)inputMap.get(ksEnter);
		// I replace the default action associated with ENTER key.
		inputMap.put(ksEnter, "finish-edit");
		inputMap.put(ksCtrlEnter, defaultEnterAction);

		actionMap.put("cancel-edit", new AbstractAction(){
			public void actionPerformed(ActionEvent e) {
				cancelEdit();
			}
		});
		
		inputMap.put(ksEscape, "cancel-edit");
		
		textArea.addFocusListener(new FocusAdapter() {
			public void focusLost(FocusEvent e) {
				commitEdit();
			}
		});
	}
	
	public void addEditorAreaListener(EditorAreaListener listener){
		listeners.add(listener);
	}
	
	public void removeEditorAreaListener(EditorAreaListener listener){
		listeners.remove(listener);
	}
	
	protected void commitEdit(){
		EditorAreaEvent event = new EditorAreaEvent(this);
		for (EditorAreaListener listener:listeners){
			listener.editCommited(event);
		}
	}
	
	protected void cancelEdit(){
		EditorAreaEvent event = new EditorAreaEvent(this);
		for (EditorAreaListener listener:listeners){
			listener.editCanceled(event);
		}
	}
	
	public String getText(){
		return textArea.getText();
	}
	
	public void setText(String text){
		textArea.setText(text);
	}
}
